#include <stdio.h>
#include <string.h>

#define MAX_LEN 100

int help();
int quit();

typedef struct tDataNode {
    char   *cmd;
    char   *desc;
    int    (*handler)();
    struct tDataNode *next;
} DataNode;

static DataNode head[] = {
    {"help", "This is menu program.", help, &head[1]},
    {.cmd = "version", .desc = "Menu program v1.0", NULL, &head[2]},
    {.cmd = "quit", .desc = "Quit menu program.", .handler = quit, .next = NULL}
}; 

DataNode* FindCmd(DataNode *head, const char *cmd);
void ShowAllCmd(DataNode *head);

int main(int argc, char *argv[])
{
    char cmd[MAX_LEN];
    while(1)
    {
        printf("Input a command: ");
        scanf("%s", cmd);
        
        DataNode *p = FindCmd(head, cmd); 
        if(NULL == p)
        {
            printf("Unknown command!\n");
            continue;
        }       

        printf("%-10s - %s\n", cmd, p->desc);
        if(NULL != p->handler)
        {
            if(-1 == p->handler())
                break;
        }             
    }

    return 0;
}

int help()
{
    ShowAllCmd(head);
    return 0;
}

int quit()
{
    return -1;
}

DataNode* FindCmd(DataNode *head, const char *cmd)
{
    if(NULL == head || NULL == cmd) return NULL;
    
    DataNode *p = head;
    while(NULL != p)
    {
        if(0 == strcmp(cmd, p->cmd))
            break;
        
        p = p->next;
    }
    
    return p;
}

void ShowAllCmd(DataNode *head)
{
    printf("Menu List:\n");
    
    DataNode *p = head;
    while(NULL != p)
    {
        printf("%-10s - %s\n", p->cmd, p->desc);
        p = p->next;
    }
}
